package com.polaris.live.widget.bubble

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.NinePatch
import android.graphics.Rect
import android.graphics.drawable.NinePatchDrawable
import android.util.AttributeSet
import android.util.LruCache
import android.view.View
import android.widget.ImageView
import androidx.appcompat.widget.AppCompatTextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import com.blankj.utilcode.util.ColorUtils
import com.bumptech.glide.Glide
import com.polaris.live.R
import com.polaris.live.common.ext.dp
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.resp.bean.decoration.UserDecorationChatBubbleExtBean
import com.polaris.live.utils.file.FileUtils
import com.polaris.live.utils.image.ImageUtils
import com.polaris.live.utils.viewscope.autoDisposeScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File

/**
 * BubbleView 气泡view
 * @author Created by 天晴 on 2024/1/29 10:36
 * @since 1.0.0
 **/
class BubbleView(context: Context, attrs: AttributeSet?) : ConstraintLayout(context, attrs) {

    private var direction = 0  //0 left  1 right
    private var lastBubbleData: UserDecorationChatBubbleExtBean? = null  //上次设置的气泡
    private var translateView: ImageView? = null
    private var translateLineLeft: View? = null
    private var translateLineRight: View? = null

    private var modifyTextId: Int = -1  //需要修改颜色的控件id
    private var modifyTextId2: Int = -1 //需要修改颜色的控件id2

    init {
        if (attrs != null) {
            val typedArray = context.obtainStyledAttributes(attrs, R.styleable.Bubble)
            try {
                direction = typedArray.getInt(R.styleable.Bubble_direction, 0)
                modifyTextId = typedArray.getResourceId(R.styleable.Bubble_modify_text_id, -1)
                modifyTextId2 = typedArray.getResourceId(R.styleable.Bubble_modify_text_id2, -1)
            } finally {
                typedArray.recycle()
            }
        }
    }

    /**
     * 绑定翻译view
     */
    fun bingTranslation(
        translateView: ImageView,
        translateLineLeft: View,
        translateLineRight: View,
    ) {
        this.translateView = translateView
        this.translateLineLeft = translateLineLeft
        this.translateLineRight = translateLineRight
    }

    /**
     * 设置默认
     */
    private fun setDef() {
        background = if (direction == 0) {
            ContextCompat.getDrawable(context, R.drawable.left_top2_r12_back_ffffff)
        } else {
            ContextCompat.getDrawable(context, R.drawable.me_default_bubble_back)
        }

        setColor(ColorUtils.getColor(R.color.color_0b0123))

        setPadding(12.dp, 12.dp, 12.dp, 12.dp)
        translateView?.setImageResource(R.drawable.ic_translate_message)
        translateLineLeft?.setBackgroundColor(ColorUtils.getColor(R.color.color_e8e8e8))
        translateLineRight?.setBackgroundColor(ColorUtils.getColor(R.color.color_e8e8e8))
    }

    fun setBubble(data: UserDecorationChatBubbleExtBean?) {
        if (data == null) {
            lastBubbleData = null
            setDef()
            return
        }
        if (data.url == lastBubbleData?.url) return
        getNinePatchDrawableByBitMap(data, {
            lastBubbleData = data
            background = it
            setColor(data)

            translateView?.also { iv ->
                if (data.translationUrl != null) {
                    Glide.with(context)
                        .load(ImageUtils.imgPath(data.translationUrl))
                        .into(iv)
                } else {
                    iv.setImageResource(R.drawable.ic_translate_message_new)
                }

                val lineColor = Color.parseColor(data.lineColor)
                translateLineLeft?.setBackgroundColor(lineColor)
                translateLineRight?.setBackgroundColor(lineColor)
            }
        }) {
            setDef()
        }
    }

    /**
     * 设置内部字体颜色
     */
    private fun setColor(data: UserDecorationChatBubbleExtBean) {
        val color = if (direction == 0) {
            Color.parseColor(data.leftColor)
        } else {
            Color.parseColor(data.rightColor)
        }
        setColor(color)
    }

    private fun setColor(color: Int) {
        if (modifyTextId != -1) {
            findViewById<AppCompatTextView>(modifyTextId).setTextColor(color)
        }
        if (modifyTextId2 != -1) {
            findViewById<AppCompatTextView>(modifyTextId2).setTextColor(color)
        }
    }

    /**
     * 从bitmap加载NinePatchDrawable
     */
    private fun getNinePatchDrawableByBitMap(
        data: UserDecorationChatBubbleExtBean,
        bitmap: Bitmap,
    ): NinePatchDrawable? {
        val chunk = bitmap.ninePatchChunk ?: return null
        val rect = data.run {
            if (left != 0 && top != 0 && right != 0 && bottom != 0) {
                Rect(left, top, right, bottom)
            } else {
                NinePatchChunk.deserialize(chunk)?.mPaddings //使用.9的宽高属性
            }
        }
        return if (rect != null && NinePatch.isNinePatchChunk(chunk)) {
            NinePatchDrawable(
                context.resources,
                bitmap,
                chunk,
                rect,
                null
            )
        } else {
            null
        }

    }

    /**
     * 从3级缓存加载获取.9Drawable
     */
    private fun getNinePatchDrawableByBitMap(
        data: UserDecorationChatBubbleExtBean,
        success: (npd: NinePatchDrawable) -> Unit,
        error: (e: Exception) -> Unit,
    ) {
        val directionUrl = if (direction == 0) data.getLeftUrl() else data.getRightUrl()
        val cacheBitmap = getNineBitMapCache(directionUrl)
        if (cacheBitmap != null) {
            getNinePatchDrawableByBitMap(data, cacheBitmap)?.let(success)
                ?: error.invoke(IllegalArgumentException("Not a. 9 graph"))
            return
        }
        val filePath = FileUtils.getFilePath(FileUtils.getBubbleFile(), data.url)
        if (File(filePath).exists()) {
            getNinePatchDrawableByBitMap(data, BitmapFactory.decodeFile(filePath))?.let(success)
                ?: error.invoke(IllegalArgumentException("Not a. 9 graph"))
        } else {
            //如果需要从网络下载则先设置默认
            setDef()

            this.autoDisposeScope.launch {
                val netBitmap = getBitMapByNet(directionUrl)
                withContext(CoroutineScopeManager.mainDispatcher) {
                    netBitmap ?: run {
                        error.invoke(IllegalArgumentException("Bitmap is null"))
                        return@withContext
                    }
                    getNinePatchDrawableByBitMap(data, netBitmap)?.let(success)
                        ?: error.invoke(IllegalArgumentException("Not a. 9 graph"))
                }
            }
        }
    }

    /**
     * 从网络加载
     */
    private suspend fun getBitMapByNet(url: String): Bitmap? {
        return DownLoadFileUtil.getNineBitMap(url)?.also {
            setCache(url, it)
        }
    }

    /**
     * 从缓存加载
     */
    private fun getNineBitMapCache(url: String): Bitmap? {
        return if (url.isEmpty()) {
            null
        } else {
            getCache(url)
        }
    }

    companion object {

        //设置10M缓存
        private val cache = object : LruCache<String, Bitmap>(10 * 1024 * 1024) {
            override fun sizeOf(key: String, value: Bitmap): Int {
                return value.byteCount
            }
        }

        @Synchronized
        fun getCache(key: String): Bitmap? {
            return cache[key]
        }

        @Synchronized
        fun setCache(key: String, value: Bitmap?) {
            cache.put(key, value)
        }
    }
}